import { EnumChatMsgExecutedState, type MyChatMsgResult } from "@/api/siderBar/model"
import { getMychatMsgdetailId, postMychatExecutecardactionId, postMychatMsgsId } from "@/api/siderBar/myChat"
import { useScroll } from '@vueuse/core'
import { message as messageInstance } from 'ant-design-vue'
import type { AnyEventManager, MessageListAnyEvent } from "../components/MessageList/types"

export function useChatMessages(sessionId: MaybeRef<MaybeUndefined<number>>) {
    const pageIndex = ref(1)
    const messages = ref<MyChatMsgResult[]>([])
    const hasNext = ref(true)
    const relativeMsgId = ref(-1)
    const loading = ref(false)
    const scrollEl = ref<HTMLElement>()
    const { y, arrivedState, measure, isScrolling } = useScroll(scrollEl, {
        behavior: 'instant',
        throttle: 30,
        onScroll() {
            if (arrivedState.top) {
                onScrollToUpper()
            }
        },
    })
    const { copy } = useCopy()
    const anyEventManager: AnyEventManager = {
        copyText({content}) {
            copy(content)
        },
        async handleRequestCard({action,message,actionType}) {
            const nextMessageId = await postMychatExecutecardactionId(toValue(sessionId)!, {
                action,
                chatMsgId: message.id
            })
            nextMessageId && await getNextMessage(nextMessageId)
            const currentMessage = messages.value.find(item => item.id === message.id)
            currentMessage!.executedState = actionType === "agreen" ? EnumChatMsgExecutedState.同意 : EnumChatMsgExecutedState.拒绝
            messageInstance.success("操作成功")
        },
        previewResume({source}) {
            open(source, "_blank")
        }
    }
    async function scrollToLast() {
        const target = scrollEl.value
        if (isScrolling.value || !target) return
        await nextTick()
        measure()
        y.value = target.scrollHeight
    }
    async function smoothRemainPosition() {
        const target = scrollEl.value
        if (!target) return
        const currentOffset = target.scrollHeight - y.value
        await nextTick()
        measure()
        y.value = target.scrollHeight - currentOffset
    }
    function fetchMessageList(refresh = false) {
        if (loading.value) return
        if (refresh) pageIndex.value = 1
        loading.value = true
        return postMychatMsgsId(toValue(sessionId)!, {
            page: {
                pageIndex: pageIndex.value,
                pageSize: 20
            },
            search: {},
            sort: {
                reverse: true
            }
        })
            .then(({ items, count }) => {
                const nextMessages = pageIndex.value === 1 ? items.reverse() : items.reverse().concat(messages.value)
                messages.value = nextMessages
                hasNext.value = count > nextMessages.length
                if (refresh) {
                    scrollToLast()
                } else {
                    smoothRemainPosition()
                }
            })
            .finally(() => {
                loading.value = false
            })
    }
    function getNextMessage(messageId: number) {
        const id = toValue(sessionId)
        if (!id || !messageId) return
        return getMychatMsgdetailId(messageId)
            .then(message => {
                messages.value.push(message)
                scrollToLast()
            })
    }
    function onScrollToUpper() {
        console.log("onScrollToUpper")
        if (hasNext.value) {
            pageIndex.value++
            fetchMessageList()
        }
    }
    function appendCustomeMessage(message: Required<Omit<MyChatMsgResult, "id" | "createTime" | "readTime" | "isRead" | "conversationId" | "executedState" | "isMember" | "cardContent" | "interviewId">>) {
        const createTime = dateFormat(void 0, "long")
        // @ts-ignore
        messages.value.push({
            ...message,
            createTime,
            readTime: createTime,
            id: relativeMsgId.value--,
            isRead: true,
            conversationId: toValue(sessionId)!
        })
    }
    function handleMessageAnyEvent(ev: MessageListAnyEvent) {
        anyEventManager[ev.type] && anyEventManager[ev.type](ev as any)
    }
    return {
        messages,
        scrollEl,
        scrollToLast,
        fetchMessageList,
        getNextMessage,
        appendCustomeMessage,
        handleMessageAnyEvent
    }
}